package com.dataStructures.linkedlist;

/**
 * 双向链表
 */
public class DoubleLinkedList {

	private final HeroNode2 head = new HeroNode2(0, "", "");

	public HeroNode2 getHead() {
		return head;
	}

	public void list() {
		// 判断链表是否为空
		if (head.next == null) {
			System.out.println("链表为空");
			return;
		}
		// 因为头节点，不能动，因此我们需要一个辅助变量来遍历
		HeroNode2 temp = head.next;
		while (temp != null) {
			// 判断是否到链表最后
			// 输出节点的信息
			System.out.println(temp);
			// 将 temp 后移， 一定小心
			temp = temp.next;
		}
	}

	public void add(HeroNode2 heroNode) {
		// 因为 head 节点不能动，因此我们需要一个辅助遍历
		HeroNode2 temp = head;
		// 遍历链表，找到最后
		while (temp.next != null) {
			// 找到链表的最后
			// 如果没有找到最后, 将将 temp 后移
			temp = temp.next;
		}
		// 当退出 while 循环时，temp 就指向了链表的最后
		// 形成一个双向链表
		temp.next = heroNode;
		heroNode.pre = temp;
	}

	public void update(HeroNode2 newHeroNode) {
		// 判断是否空
		if (head.next == null) {
			System.out.println("链表为空~");
			return;
		}
		// 找到需要修改的节点, 根据 no 编号
		// 定义一个辅助变量
		HeroNode2 temp = head.next;
		// 表示是否找到该节点
		boolean flag = false;
		while (true) {
			if (temp == null) {
				break; // 已经遍历完链表
			}
			if (temp.no == newHeroNode.no) {
				flag = true;
				break;
			}
			temp = temp.next;
		}
		// 根据 flag 判断是否找到要修改的节点
		if (flag) {
			temp.name = newHeroNode.name;
			temp.nickname = newHeroNode.nickname;
		} else { // 没有找到
			System.out.printf("没有找到 编号 %d 的节点，不能修改\n", newHeroNode.no);
		}
	}

	public void del(int no) {
		// 判断当前链表是否为空
		if (head.next == null) {
			System.out.println("链表为空，无法删除");
			return;
		}
		HeroNode2 temp = head.next;
		boolean flag = false;
		while (true) {
			if (temp == null) {
				break;
			}
			if (temp.no == no) {
				// 找到的待删除节点的前一个节点
				flag = true;
				break;
			}
			temp = temp.next;
		}
		// 判断 flag
		if (flag) {
			// 可以删除
			// temp.next = temp.next.next;[单向链表]
			temp.pre.next = temp.next;
			// 这里我们的代码有问题?
			// 如果是最后一个节点，就不需要执行下面这句话，否则出现空指针
			if (temp.next != null) {
				temp.next.pre = temp.pre;
			}
		} else {
			System.out.printf("要删除的 %d 节点不存在\n", no);
		}
	}
}

class HeroNode2 {
	public int no;
	public String name;
	public String nickname;
	// 指向下一个节点, 默认为 null
	public HeroNode2 next;
	// 指向前一个节点, 默认为 null
	public HeroNode2 pre;

	public HeroNode2(int no, String name, String nickname) {
		this.no = no;
		this.name = name;
		this.nickname = nickname;
	}

	@Override
	public String toString() {
		return "HeroNode [no=" + no + ", name=" + name + ", nickname=" + nickname + "]";
	}
}
